package com.acane.instagram.feature.me

import android.content.Context
import android.graphics.Bitmap
import android.media.MediaMetadataRetriever
import android.net.Uri
import android.util.Log
import android.widget.Toast
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.acane.instagram.core.model.PostInfo
import com.acane.instagram.core.model.UserInfo
import com.acane.instagram.core.model.network.datasource.MyRetrofitDatasource
import com.acane.instagram.feature.common.SessionManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okio.IOException
import java.io.File
import java.io.FileOutputStream

class MeViewModel: ViewModel() {
    private val _postDatum = MutableStateFlow<List<PostInfo>>(emptyList())
    val postDatum: MutableStateFlow<List<PostInfo>> = _postDatum
    private val _gridPostData = MutableStateFlow<List<PostInfo>>(emptyList())
    val gridPostData: MutableStateFlow<List<PostInfo>> = _gridPostData
    private val _videoPostData = MutableStateFlow<List<PostInfo>>(emptyList())
    val videoPostData: MutableStateFlow<List<PostInfo>> = _videoPostData
    val gridBoxInfo: MutableStateFlow<Map<PostInfo, String>> = MutableStateFlow(emptyMap())

    private val _currentUserInfo = MutableStateFlow<UserInfo>(UserInfo())
    val currentUserInfo: MutableStateFlow<UserInfo> = _currentUserInfo


    var serverFileName by mutableStateOf<String?>(null)
    var selectedImageUri by mutableStateOf<Uri?>(null)

    fun updateUserInfo(userInfo: UserInfo, context: Context) {
        // 更新本地用户信息
        _currentUserInfo.value = userInfo
        viewModelScope.launch {
            // 更新数数据库用户信息
            val response = MyRetrofitDatasource.updateUserInfo(userInfo)
            if (response.data != null) {
                // 弹出提示
                Toast.makeText(context, "更新成功", Toast.LENGTH_SHORT).show()
            } else {
                // 弹出提示
                Toast.makeText(context, "更新失败", Toast.LENGTH_SHORT).show()
            }
            Log.d("MeViewModel", "更新后的用户信息: ${response.data}")
        }
    }

    fun loadServerAvatar(userId: String) {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val response = MyRetrofitDatasource.getUserAvatar(userId)
                val fileName = response.data
                Log.d("avatar", "获取到头像文件名: $fileName")
                serverFileName = fileName

            } catch (e: Exception) {
                println("🔴 网络请求异常: ${e.message}")
            }
        }
    }

    fun uploadImage(uri: Uri, context: Context, userId: String) {
        viewModelScope.launch(Dispatchers.IO) {

                val filePart = uri.toMultipartBodyPart(
                    context = context,
                    partName = "file",
                    fileName = null
                )

                val userIdBody = userId.toRequestBody("text/plain".toMediaType())

                val response = MyRetrofitDatasource.uploadAvatar(
                    userId = userIdBody,
                    file = filePart
                )
            Log.d("avatar", "上传头像文件名: $response")

            withContext(Dispatchers.Main) {
                val serverFileName = response.data
                this@MeViewModel.serverFileName = serverFileName
                selectedImageUri = uri
            }
        }
    }

    private fun Uri.toMultipartBodyPart(
        context: Context,
        partName: String,
        fileName: String? // 允许传递null
    ): MultipartBody.Part {
        return context.contentResolver.openInputStream(this)?.use { stream ->
            // 获取实际MIME类型
            val mimeType = context.contentResolver.getType(this) ?: "application/octet-stream"
            val requestBody = stream.readBytes().toRequestBody(mimeType.toMediaType())

            // 如果fileName为null，由后端决定文件名
            MultipartBody.Part.createFormData(
                partName,
                fileName ?: "", // 空文件名让后端处理
                requestBody
            )
        } ?: throw IOException("无法读取文件")
    }


     fun loadCurrentUserInfo() {
        viewModelScope.launch {
            _currentUserInfo.value = SessionManager.currentUser?.id?.let {
                MyRetrofitDatasource.getUserById(
                    it
                ).data
            }!!
        }
    }

    // 独立缩略图生成函数
    suspend fun generateVideoThumbnail(
        context: Context,
        videoUrl: String,
        timeMicroSec: Long = 0
    ): ImageBitmap? = withContext(Dispatchers.IO) {
        val retriever = MediaMetadataRetriever()
        try {
            val videoFile = downloadVideo(context, videoUrl)
            if (videoFile != null) {
                retriever.setDataSource(videoFile.absolutePath)
                val bitmap = getFrame(retriever, timeMicroSec)
                videoFile.delete() // 删除临时文件
                return@withContext bitmap
            }
        } catch (e: Exception) {
            Log.e("MeViewModel", "生成缩略图失败", e)
        } finally {
            retriever.release()
        }
        return@withContext null
    }

    private fun downloadVideo(context: Context, videoUrl: String): File? {
        val client = OkHttpClient()
        val request = Request.Builder()
            .url(videoUrl)
            .build()

        client.newCall(request).execute().use { response ->
            if (!response.isSuccessful) {
                Log.e("MeViewModel", "下载视频失败: $response")
                throw IOException("Unexpected code $response")
            }

            val videoFile = File.createTempFile("video", ".mp4", context.cacheDir)
            FileOutputStream(videoFile).use { fos ->
                response.body?.byteStream()?.use { inputStream ->
                    val buffer = ByteArray(4096)
                    var bytesRead: Int
                    while (inputStream.read(buffer).also { bytesRead = it } != -1) {
                        fos.write(buffer, 0, bytesRead)
                    }
                }
            }
            Log.d("MeViewModel", "视频下载成功: ${videoFile.absolutePath}")
            return videoFile
        }
    }

    fun getFrame(retriever: MediaMetadataRetriever, timeMicroSec: Long): ImageBitmap? {
        return retriever.getFrameAtTime(timeMicroSec)?.let { bitmap ->
            // 优化缩略图尺寸
            Bitmap.createScaledBitmap(
                bitmap,
                bitmap.width / 4,  // 缩小尺寸提升性能
                bitmap.height / 4,
                true
            ).asImageBitmap()
        }
    }

    private var _refresh = MutableStateFlow<Boolean>(false)
    val refresh = _refresh

    fun startRefresh() {
        viewModelScope.launch {
            _refresh.value = true
            delay(1000)
            _refresh.value = false
            loadCurrentUserInfo()
            refreshPosts()
        }
    }

    init {
        loadInitialData()
    }


    fun loadGridPostData() {
        val gridPosts = mutableListOf<PostInfo>()
        val videoPosts = mutableListOf<PostInfo>()

        postDatum.value.forEach { post ->
            when (post.showRange) {
                "grid_and_reels" -> {
                    if (post.urls.size == 1 && post.urls.first().endsWith(".mp4")) {
                        videoPosts.add(post)
                    }
                    gridPosts.add(post)
                }
                "reels" -> {
                    videoPosts.add(post)
                }
            }
        }

        _gridPostData.value = gridPosts
        _videoPostData.value = videoPosts

        _gridPostData.value.forEach { post ->
            val uris = post.urls
            if (uris.size > 1) {
                gridBoxInfo.value = gridBoxInfo.value + (post to "isGrid")

            } else if (uris.size == 1 && uris.first().endsWith(".mp4")) {

                gridBoxInfo.value = gridBoxInfo.value + (post to "isVideo")
            }
        }
        Log.d("MeViewModel", "gridBoxInfo:\n ${gridBoxInfo.value} ")
    }

// MeViewModel.kt
fun refreshPosts() {
    viewModelScope.launch {
//        // 清空现有数据
//        _postDatum.value = emptyList()
//        _gridPostData.value = emptyList()
//        _videoPostData.value = emptyList()

        // 重新加载数据
        loadData().join()
        loadGridPostData()
        //loadVideoPostData()

        Log.d("MeViewModel", "数据刷新完成")
    }
}



    fun loadInitialData() {
        viewModelScope.launch {
            // 步骤 0：加载当前用户信息
            loadCurrentUserInfo()
            // 步骤 1：先获取主数据
            loadData().join() // 等待数据加载完成

            // 步骤 2：处理后续过滤
            loadGridPostData()
            //loadVideoPostData()

            // 验证数据
            Log.d("MeViewModel", "Grid数据: ${gridPostData.value}")
            Log.d("MeViewModel", "Video数据: ${videoPostData.value}")
        }
    }

    // 修改为返回 Job 用于同步
    private fun loadData(): Job = viewModelScope.launch {
        Log.d("MeViewModel", "开始初始化数据")
        val newData = SessionManager.currentUser?.id?.let {
            try {
                MyRetrofitDatasource.getPostListById(it).data
            } catch (e: Exception) {
                Log.e("MeViewModel", "网络请求失败", e)
                emptyList<PostInfo>()
            }
        } ?: emptyList()
        _postDatum.value = newData
    }

    suspend fun getPostPosition(postId: String, userId: String) : Int
    {
        val postData = MyRetrofitDatasource.getPostListById(userId).data
        if (postData != null) {
            return postData.indexOfFirst { it.id == postId }
        }
        return 0
    }

}